home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / aux / mail-dm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  7.7 KB  |  427 lines

  1. #include <arpa/netopen.h>
  2. #include "srvrftp.h"
  3. #include <statbuf.h>
  4. #include <arpa/hostnames.h>
  5. #include <io_buf.h>
  6. #include <arpa/mail.h>
  7. #include <ident.h>
  8. #include <signal.h>
  9. #include <log.h>
  10. extern int fout;
  11.  
  12. static char SccsId[] = "@(#)mail-dm.c    4.1    7/25/83";
  13.  
  14. /*
  15. Name:
  16.     mail
  17.  
  18. Function:
  19.     handle the MAIL <user> command over the command connection
  20.  
  21. Algorithm:
  22.     see if we have a known user
  23.  
  24.     if mailbox file can't be gotten
  25.         return
  26.     tell him it is ok to go ahead with mail
  27.  
  28.     while he doesn't type a period
  29.         read and write data
  30.     say completed
  31.  
  32. Parameters:
  33.     username in arg
  34.  
  35. Returns:
  36.     nothing
  37.  
  38. Globals:
  39.     arg
  40.     username=
  41.  
  42. Calls:
  43.     strmove
  44.     getuser
  45.     loguser
  46.     openmail
  47.     closemail
  48.     getline
  49.     chown (sys)
  50.     time (sys)
  51.     printf (sys)
  52.     getch    (util)
  53.     putch    (util)
  54.  
  55. Called by:
  56.     main thru command array
  57.  
  58. History:
  59.     initial coding         Mark Kampe UCLA-ATS
  60.     modified 4/13/76 by S. F. Holmgren for Illinois version
  61.     modified 6/30/76 by S. F. Holmgren to call getmbox
  62.     modified 10/18/76 by J. S. Kravitz to improve net mail header
  63.     chown removed by R. Balocca @ CAC, Sunday 1977 February 20
  64.     getline removed and limit on line length removed by using
  65.     getch and putch added by R. Balocca @ CAC, 1977 March 8 Tuesday
  66.     Fixed oversight in above (forgot to translate <crlf> to <lf>)
  67.         1977 March 10 Thursday by Rick Balocca @ CAC
  68.     Added openmail & closemail, added logging, and fixed several
  69.         bugs on or about 12/21/79 by Eric Allman, UCB/INGRES.
  70.     Changed to always accept mail -- bad mail will be sent back --
  71.         1/9/80 by Eric Allman, UCB/INGRES.
  72.     Don't print out 350 enter mail or 256 mail accepted messages --
  73.         sendmail will do that.  8/19/81 Eric Allman UCB/INGRES.
  74. */
  75. #define gt (c = getch())
  76. mail()
  77. {
  78.     register char *p;    /* general use */
  79.     register int c;
  80.     int i;
  81.  
  82.     /* extern struct io_buf obuf; */
  83.  
  84.     /* get to open mailbox file descriptor */
  85.     fflush(&fout);
  86.     if( (fout = openmail(arg, 0)) < 0 )
  87.         return;
  88.  
  89.     for(;;)                /* while no error or <crlf>.<crlf> */
  90.     {
  91.         /* we are at beginning of line */
  92.  
  93.         if(gt=='.')            /*"."*/
  94.         {
  95.             if(gt=='\r')            /*".\r"*/
  96.             {
  97.                 if(gt=='\n')            /*".\r\n"*/
  98.                 {
  99.                     /* end of message */
  100.                     break;
  101.                 }
  102.                 else
  103.                 {                /*".\r"c*/
  104.                     putch('.');
  105.                     putch('\r');
  106.                 }
  107.             }
  108.             else                /*"."c"*/
  109.                 putch('.');
  110.         }
  111.                                 /*"-"*/
  112.                     /* c */
  113.         for(;;)
  114.         {
  115.             for(; c != '\r'; gt)
  116.             {
  117.                 if( c < 0 )
  118.                 {
  119.                     fflush(&fout);
  120.                     write(fout, "\n***** Sender aborted connection *****\n", 39);
  121.                     goto out;
  122.                 }
  123.                 else
  124.                     putch(c);
  125.             }
  126.     
  127.                         /*"\r"*/
  128.             if( gt == '\n' )
  129.             {            /*"\r\n"*/
  130. crlf:
  131.                 putch('\n');
  132.                 break;
  133.             }
  134.             else
  135.             {            /*"\r"c*/
  136. crc:
  137.                 putch('\r');
  138.                 if(c=='\0')
  139.                     gt;    /* "\r\0" */
  140.                         /* is arpa escape for "\r" */
  141.             }
  142.         }
  143.     }
  144.  
  145. out:
  146.     fflush(&fout);
  147.     closemail(fout);
  148. }
  149.  
  150. /*
  151. Name:
  152.     datamail
  153.  
  154. Function:
  155.     handle the MLFL command
  156.  
  157. Algorithm:
  158.     fork
  159.         make sure we have a valid user
  160.             say bad user and exit
  161.         send sock command
  162.         open data connection
  163.         get open mailbox file descriptor
  164.         call rcvdata to receive mail
  165.  
  166. Parameters:
  167.     username in arg
  168.  
  169. Returns:
  170.     nothing
  171.  
  172. Globals:
  173.     arg
  174.  
  175. Calls:
  176.     fork (sys)
  177.     strmove
  178.     netreply
  179.     sendsock
  180.     dataconnection
  181.     getmbox
  182.     rcvdata
  183.     printf (sys)
  184.     time (sys)
  185.  
  186. Called by:
  187.     main thru command array 
  188.  
  189. History:
  190.     initial coding 4/13/76 by S. F. Holmgren
  191.     modified 10/18/76 by J. S. Kravitz to put net mail header
  192.     chown removed by R. Balocca @ CAC, Sunday 1977 February 20
  193. */
  194. datamail()
  195. {
  196.     register netdata;
  197.     /* register mboxfid; */
  198.     register int i;
  199.  
  200.     i = fork();
  201.     if (i < 0)
  202.     {
  203.         netreply("455 Mail server temporarily unavailable\r\n");
  204.         return;
  205.     }
  206.     else if (i == 0)
  207.     {
  208.         fflush(&fout);
  209.         if ((fout = openmail(arg, 1)) < 0)
  210.             exit(3);
  211.  
  212.         /* send sock command */
  213.         sendsock( U4 );
  214.  
  215.         /* open data connection */
  216.         netdata = dataconnection( U4 );
  217.  
  218.         /* say its ok to proceed */
  219.         numreply( NUM250 );
  220.  
  221.         /* get data from net connection and copy to mail file */
  222.         /* rcvdata( netdata,mboxfid ); */
  223.         if (rcvdata(netdata, fout) < 0)
  224.             exit(1);
  225.  
  226.         /* close the mail, see if ok; if so say ok */
  227.         fflush(&fout);
  228.         closemail(fout);
  229.  
  230.         exit( 0 );
  231.     }
  232. }
  233. /*
  234. **  OPENMAIL -- Open a channel to the mail server
  235. **
  236. **    Gets the mail server started up ready to handle our
  237. **    mail.
  238. **
  239. **    Algorithm:
  240. **        See if the user is specified.
  241. **            If not, send to user "root".
  242. **        See if the user exists.
  243. **            If not, signal error 450 and return.
  244. **        Fork.
  245. **        Create a pipe
  246. **            Signal "unavailable" and exit on failure.
  247. **        Fork.
  248. **            Signal "unavailable" and exit on failure
  249. **            In child:
  250. **                Call mailer: /etc/delivermail is preferred.
  251. **            In parent:
  252. **                Avoid pipe signals in case delivermail dies.
  253. **                Save the childs pid.
  254. **                Return file descriptor.
  255. **
  256. **    Notes:
  257. **        The check to see if the user actually exists should
  258. **        go away so that we can do real mail forwarding.
  259. **
  260. **    Parameters:
  261. **        who -- the user to send the mail to.
  262. **        mode -- 0 -- called from mail
  263. **            1 -- called from mlfl
  264. **
  265. **    Returns:
  266. **        File descriptor to send mail to.
  267. **        -1 on failure.
  268. **
  269. **    Side Effects:
  270. **        Forks /etc/delivermail or /bin/mail or /usr/bin/mail.
  271. **        Becomes "network" in the child.
  272. **
  273. **    Requires:
  274. **        strmove
  275. **        getuser
  276. **        netreply
  277. **        pipe (sys)
  278. **        fork (sys)
  279. **        close (sys)
  280. **        dup (sys)
  281. **        execl (sys)
  282. **        signal (sys)
  283. **        exit (sys)
  284. **
  285. **    Called By:
  286. **        mail
  287. **        datamail
  288. **
  289. **    History:
  290. **        1/9/80 -- Added 050 & 455 reply messages if execl's
  291. **            fail.  Eric Allman UCB/INGRES.
  292. **        11/26/79 -- Modified to map upper case to lower
  293. **            case.  Eric Allman UCB/INGRES.
  294. **        11/10/79 -- Written by Eric Allman UCB/INGRES
  295. **        3/6/80 -- Dropped case mapping; delivermail does
  296. **            that now.  EPA UCB/INGRES.
  297. **        8/19/81 -- Added "mode" parameter; call sendmail
  298. **            instead of delivermail.  EPA
  299. */
  300.  
  301. int Mail_pid;
  302. char *Mail_user;
  303.  
  304. openmail(who, mode)
  305.     char *who;
  306.     int mode;
  307. {
  308.     register char *w;
  309.     register int i;
  310.     int pvect[2];
  311.     register char *p;
  312.  
  313.     w = who;
  314.     if (w == 0)
  315.         w = "root";
  316.     Mail_user = w;
  317.  
  318.     /* see if the user exists */
  319.     strmove(w, username);
  320.  
  321.     /* try to get a pipe to the mailer */
  322.     if (pipe(pvect) < 0)
  323.     {
  324.       unavailable:
  325.         netreply("455 Mail server temporarily unavailable\r\n");
  326.         return (-1);
  327.     }
  328.  
  329.     /* fork */
  330.     i = fork();
  331.     if (i < 0)
  332.     {
  333.         /* failure */
  334.         close(pvect[0]);
  335.         close(pvect[1]);
  336.         goto unavailable;
  337.     }
  338.     else if (i == 0)
  339.     {
  340.         /* child */
  341.         close(pvect[1]);
  342.         close(0);
  343.         dup(pvect[0]);
  344.         close(pvect[0]);
  345.         setuid(NETUID);
  346.  
  347.         /* try to call something to deliver the mail */
  348.         execl("/etc/sendmail", "sendmail", "-v", mode == 1 ? "-af" : "-am", w, 0);
  349.  
  350.         /* doesn't seem to be anything around */
  351.         netreply("455 Mail server unavailable\r\n");
  352.         exit(3);
  353.     }
  354.  
  355.     /* else parent */
  356.     signal(SIGPIPE, SIG_IGN);
  357.     Mail_pid = i;
  358.     close(pvect[0]);
  359.     return (pvect[1]);
  360. }
  361. /*
  362. **  CLOSEMAIL -- Close the mail file and get actual status
  363. **
  364. **    The mail file is closed.
  365. **
  366. **    Algorithm:
  367. **        Wait for the mailer to die.
  368. **            If it wasn't there, be non-comittal.
  369. **        If it died a violent death, give error.
  370. **
  371. **    Parameters:
  372. **        fd -- the file descriptor of the mail file.
  373. **
  374. **    Returns:
  375. **        none.
  376. **
  377. **    Side Effects:
  378. **        mailer is soaked up.
  379. **
  380. **    Requires:
  381. **        close (sys)
  382. **        wait (sys)
  383. **
  384. **    Called By:
  385. **        mail
  386. **        datamail
  387. **
  388. **    History:
  389. **        1/9/80 -- Changed to not check for errors in mailing,
  390. **            since these will be mailed back.
  391. **        11/10/79 -- Written by Eric Allman UCB/INGRES.
  392. */
  393.  
  394. closemail(fd)
  395.     int fd;
  396. {
  397.     auto int st;
  398.     register int i;
  399.  
  400.     /* close the pipe -- mail should go away */
  401.     close(fd);
  402.  
  403.     /* wait for its body */
  404.     while ((i = wait(&st)) != Mail_pid)
  405.     {
  406.         if (i < 0)
  407.         {
  408.             /* how did this happen? */
  409.             logmsg(LOG_ERR, "mail from host %d to %s: no child",
  410.                 openparams.o_frnhost & 0377, Mail_user);
  411.             goto unavailable;
  412.         }
  413.     }
  414.  
  415.     /* 'st' is now the status of the mailer */
  416.     if ((st & 0377) != 0)
  417.     {
  418.         logmsg(LOG_ERR, "mail from host %d to %s: status %o",
  419.             openparams.o_frnhost & 0377, Mail_user, st);
  420. unavailable:
  421.         netreply("455 Mail not delivered -- local system error\r\n");
  422.         return (-1);
  423.     }
  424.  
  425.     return (0);
  426. }
  427.